from entity import *

import os
import random
import json
import time
class BankSystem:
    """银行管理系统主类 - 组合多个组件"""
    # 管理员信息
    ADMIN_USERNAME = 'admin'
    ADMIN_PASSWORD = '12345'

    def __init__(self):
        # 使用组合方式集成数据存储
        self._data_storage = DataStorage(
            os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bank_data_oop.json')
        )
        self._accounts = {}
        self._load_accounts()

    def _load_accounts(self):
        """加载账户数据"""
        data = self._data_storage.load_data()
        # 从字典数据重建账户对象
        for account_id, account_data in data.items():
            account = BankAccount(
                account_id,
                account_data['owner_name'],
                account_data['id_card'],
                account_data['phone'],
                account_data['password']
            )
            # 恢复其他属性
            account._balance = account_data.get('balance', 0.0)
            account._status = account_data.get('status', 'active')
            account._wrong_password_count = account_data.get('wrong_password_count', 0)
            self._accounts[account_id] = account

    def _save_accounts(self):
        """保存账户数据"""
        # 将账户对象转换为字典数据
        data = {}
        for account_id, account in self._accounts.items():
            data[account_id] = account.to_dict()
        return self._data_storage.save_data(data)

    def admin_login(self):
        """管理员登录"""
        username = input("请输入管理员账户: ")
        password = input("请输入密码: ")

        if username == self.ADMIN_USERNAME and password == self.ADMIN_PASSWORD:
            print("操作成功，请稍后.......")
            return True
        else:
            print("输入密码有误......." if username == self.ADMIN_USERNAME else "管理员账户输入错误.......")
            return False

    def show_welcome(self):
        """显示欢迎界面"""
        print("*" * 50)
        print("***" + "欢迎登录银行管理系统".center(44) + "***")
        print("*" * 50)

    def show_menu(self):
        """显示主菜单"""
        print("*" * 50)
        print("***" + "1.开户(1)".ljust(22) + "2.查询(2)" + "***")
        print("***" + "3.取款(3)".ljust(22) + "4.存款(4)" + "***")
        print("***" + "5.转账(5)".ljust(22) + "6.锁定(6)" + "***")
        print("***" + "7.解锁(7)".ljust(22) + "    " + "***")
        print("***" + "退出(Q)".ljust(22) + "    " + "***")
        print("*" * 50)

    def create_account(self):
        """开户功能"""
        print("\n===== 开户业务 =====")

        try:
            # 收集用户信息
            name = input("请输入姓名: ").strip()
            id_card = input("请输入身份证号: ").strip()
            phone = input("请输入手机号: ").strip()

            # 验证预存金额
            initial_balance = float(input("请输入预存金额: "))

            # 设置密码
            while True:
                password = input("请设置密码: ")
                confirm_password = input("请确认密码: ")
                if password == confirm_password:
                    break
                else:
                    print("两次输入的密码不一致，请重新设置！")

            # 使用工厂类创建账户
            account = AccountFactory.create_bank_account(
                name, id_card, phone, password, initial_balance
            )

            # 检查卡号是否重复
            while account.account_id in self._accounts:
                account = AccountFactory.create_bank_account(
                    name, id_card, phone, password, initial_balance
                )

            # 保存账户
            self._accounts[account.account_id] = account
            self._save_accounts()

            print(f"\n开户成功！")
            print(f"您的卡号是: {account.account_id}")
            print(f"请妥善保管您的卡号和密码！")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"开户过程中发生错误: {e}")

    def query_balance(self):
        """查询余额功能"""
        print("\n===== 查询余额业务 =====")

        try:
            # 获取卡号
            card_number = input("请输入卡号: ").strip()

            # 验证卡号
            if card_number not in self._accounts:
                print("卡号不存在！")
                return

            account = self._accounts[card_number]

            # 检查账户状态
            if account.status == 'locked':
                print("账户已被锁定！")
                return

            # 验证密码
            if not account.verify_password(input("请输入密码: ")):
                print("密码错误！")
                return

            # 显示余额
            print(f"您的账户余额为: {account.balance} 元")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"查询过程中发生错误: {e}")

    def withdraw(self):
        """取款功能"""
        print("\n===== 取款业务 =====")

        try:
            # 获取卡号
            card_number = input("请输入卡号: ").strip()

            # 验证卡号
            if card_number not in self._accounts:
                print("卡号不存在！")
                return

            account = self._accounts[card_number]

            # 验证密码
            if not account.verify_password(input("请输入密码: ")):
                print("密码错误！")
                return

            # 获取取款金额
            amount = float(input("请输入取款金额: "))

            # 执行取款
            new_balance = account.withdraw(amount)
            self._save_accounts()

            print(f"取款成功！当前余额: {new_balance} 元")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"取款过程中发生错误: {e}")

    def deposit(self):
        """存款功能"""
        print("\n===== 存款业务 =====")

        try:
            # 获取卡号
            card_number = input("请输入卡号: ").strip()

            # 验证卡号
            if card_number not in self._accounts:
                print("卡号不存在！")
                return

            account = self._accounts[card_number]

            # 验证密码
            if not account.verify_password(input("请输入密码: ")):
                print("密码错误！")
                return

            # 获取存款金额
            amount = float(input("请输入存款金额: "))

            # 执行存款
            new_balance = account.deposit(amount)
            self._save_accounts()

            print(f"存款成功！当前余额: {new_balance} 元")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"存款过程中发生错误: {e}")

    def transfer(self):
        """转账功能"""
        print("\n===== 转账业务 =====")

        try:
            # 获取转出卡号
            from_card = input("请输入转出卡号: ").strip()
            to_card = input("请输入转入卡号: ").strip()

            # 验证卡号
            if from_card not in self._accounts or to_card not in self._accounts:
                print("卡号不存在！")
                return

            from_account = self._accounts[from_card]
            to_account = self._accounts[to_card]

            # 获取转账金额
            amount = float(input("请输入转账金额: "))

            # 执行转账
            BankTransaction.transfer(from_account, to_account, amount, input("请输入密码: "))
            self._save_accounts()

            print(f"转账成功！转出卡剩余余额: {from_account.balance} 元")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"转账过程中发生错误: {e}")

    def lock_account(self):
        """锁定账户功能"""
        print("\n===== 锁定账户业务 =====")

        try:
            # 获取卡号
            card_number = input("请输入要锁定的卡号: ").strip()

            # 验证卡号
            if card_number not in self._accounts:
                print("卡号不存在！")
                return

            account = self._accounts[card_number]

            # 检查账户状态
            if account.status == 'locked':
                print("该账户已经被锁定！")
                return

            # 验证密码
            if not account.verify_password(input("请输入密码: ")):
                print("密码错误！")
                return

            # 锁定账户
            account.lock()
            self._save_accounts()

            print("账户锁定成功！")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"锁定过程中发生错误: {e}")

    def unlock_account(self):
        """解锁账户功能"""
        print("\n===== 解锁账户业务 =====")

        try:
            # 获取卡号
            card_number = input("请输入要解锁的卡号: ").strip()

            # 验证卡号
            if card_number not in self._accounts:
                print("卡号不存在！")
                return

            account = self._accounts[card_number]

            # 检查账户状态
            if account.status == 'active':
                print("该账户已经处于解锁状态！")
                return

            # 验证密码
            if not account.verify_password(input("请输入密码: ")):
                print("密码错误！")
                return

            # 解锁账户
            account.unlock()
            self._save_accounts()

            print("账户解锁成功！")

        except ValueError as e:
            print(f"错误: {e}")
        except Exception as e:
            print(f"解锁过程中发生错误: {e}")

    def admin_logout(self):
        """管理员退出验证"""
        print("\n请确认是否退出系统")
        username = input("请再次输入管理员账户: ")
        password = input("请再次输入密码: ")

        return username == self.ADMIN_USERNAME and password == self.ADMIN_PASSWORD

    def run(self):
        """运行银行管理系统"""
        try:
            # 显示欢迎界面
            self.show_welcome()

            # 管理员登录
            if not self.admin_login():
                return

            # 主菜单循环
            while True:
                try:
                    # 显示主菜单
                    self.show_menu()

                    # 获取用户选择
                    choice = input("请选择功能 (1-7, q退出): ").strip()

                    # 根据选择执行相应功能
                    if choice == '1':
                        self.create_account()
                    elif choice == '2':
                        self.query_balance()
                    elif choice == '3':
                        self.withdraw()
                    elif choice == '4':
                        self.deposit()
                    elif choice == '5':
                        self.transfer()
                    elif choice == '6':
                        self.lock_account()
                    elif choice == '7':
                        self.unlock_account()
                    elif choice.lower() == 'q':
                        # 退出系统需要管理员验证
                        if self.admin_logout():
                            print("\n感谢使用银行管理系统，再见！")
                            break
                        else:
                            print("\n退出失败，返回主菜单。")
                    else:
                        print("\n无效的选择，请重新输入！")

                    # 每次操作后暂停
                    input("\n按回车键继续...")

                except KeyboardInterrupt:
                    print("\n\n操作被用户中断，返回主菜单。")
                    input("\n按回车键继续...")

        except Exception as e:
            print(f"\n系统发生错误: {e}")
        finally:
            # 确保数据被保存
            if self._save_accounts():
                print("\n数据已成功保存。")
            else:
                print("\n警告：数据保存失败。")


if __name__ == "__main__":
    bank_system = BankSystem()
    bank_system.run()